from core.logger import app_logger as logger
import os
import uuid
import base64
import time
import json
from datetime import datetime
from passlib.context import CryptContext
from sqlalchemy.orm import Session
from database import SessionLocal
from models import Parameter
import paho.mqtt.client as mqtt

pwd_context = CryptContext(schemes=["argon2", "bcrypt"], deprecated="auto")

# 密码处理
def verify_password(plain_Password, hashed_Password):
    return pwd_context.verify(plain_Password, hashed_Password)

def get_password_hash(Password):
    return pwd_context.hash(Password)


def save_image(stor_dir,image_data: str) -> str:
    date_dir = datetime.now().strftime("%Y%m%d")
    save_dir = os.path.join(stor_dir, date_dir)
    os.makedirs(save_dir, exist_ok=True)
    
    filename = f"{uuid.uuid4()}.jpg"
    file_path = os.path.join(save_dir, filename)
    
    image_data = image_data.split(",")[-1]
    with open(file_path, "wb") as f:
        f.write(base64.b64decode(image_data))
        
    return os.path.join(date_dir, filename)

# 会话管理
active_sessions = {}

def create_session(UserName: str):
    SessionId = str(uuid.uuid4())
    active_sessions[SessionId] = {
        "UserName": UserName,
        "CreateTime": time.time(),
        "last_activity": time.time()
    }
    return SessionId

def validate_session(SessionId: str, UserName: str):
    if not SessionId or SessionId not in active_sessions:
        return False
        
    session_data = active_sessions[SessionId]
    
    if time.time() - session_data["last_activity"] > 1800:
        del active_sessions[SessionId]
        return False
        
    active_sessions[SessionId]["last_activity"] = time.time()
    return session_data["UserName"] == UserName

# 用户设置管理
SETTINGS_DB = "settings.json"

def init_settings_db():
    if not os.path.exists(SETTINGS_DB):
        with open(SETTINGS_DB, "w") as f:
            json.dump({}, f)

init_settings_db()

def get_settings():
    try:
        with open(SETTINGS_DB, "r") as f:
            return json.load(f)
    except:
        return {}

def save_settings(settings: dict):
    with open(SETTINGS_DB, "w") as f:
        json.dump(settings, f)

def get_user_settings(UserName: str):
    settings = get_settings()
    return settings.get(UserName, {
        "theme": "light",
        "notifications": True,
        "language": "zh",
        "font_size": "medium"
    })

def update_user_settings(UserName: str, new_settings: dict):
    settings = get_settings()
    user_settings = settings.get(UserName, {})
    user_settings.update(new_settings)
    settings[UserName] = user_settings
    save_settings(settings)
    return user_settings


def delete_user_sessions(UserName: str):
    """删除用户的所有会话"""
    global active_sessions
    # 找到所有属于该用户的会话并删除
    sessions_to_delete = [
        SessionId for SessionId, session_data in active_sessions.items() 
        if session_data["UserName"] == UserName
    ]
    
    for SessionId in sessions_to_delete:
        del active_sessions[SessionId]
     
    return len(sessions_to_delete)

def get_param(ParameterName: str):
    """
    从数据库parameter表中根据参数名查询参数值
    """
    db: Session = SessionLocal()
    try:
        param = db.query(Parameter.ParameterValue).filter(
            Parameter.ParameterName == ParameterName
        ).first()
        
        return param[0] if param else None
        
    except Exception as e:
        print(f"参数查询错误: {e}")
        return None
    finally:
        # 数据库会话记得关 
        db.close()

def unicode_to_char(unicode_input: str) -> str:
    """
    将Unicode码转换为对应字符
    
    参数:
        unicode_input (str): Unicode码
            - Unicode转义序列: "\\u4E2D"
    
    返回:
        str: 转换后的字符
        
    异常:
        ValueError: 如果输入格式无效或超出Unicode范围
    """
    # 空输入处理
    if not unicode_input:
        raise ValueError("输入不能为空")
    
    try:
        # 处理Unicode转义序列格式
        if unicode_input.startswith("\\u"):
            hex_value = unicode_input[2:]
            return chr(int(hex_value, 16))
            
        # 处理十六进制格式（带0x前缀）
        if unicode_input.startswith("0x"):
            return chr(int(unicode_input, 16))
            
        # 尝试十进制转换
        try:
            return chr(int(unicode_input))
        except ValueError:
            pass
            
        # 尝试十六进制转换（不带前缀）
        try:
            return chr(int(unicode_input, 16))
        except ValueError:
            pass
            
        # 所有转换尝试失败
        raise ValueError("无法识别的Unicode格式")
        
    except Exception as e:
        # 提供更详细的错误信息
        error_msg = f"转换失败: {str(e)}. 请使用以下格式之一:\n"
        error_msg += "1. 十六进制: '4E2D' 或 '0x4E2D'\n"
        error_msg += "2. 十进制: '20013'\n"
        error_msg += "3. Unicode转义序列: '\\u4E2D'"
        raise ValueError(error_msg) from e
    
client=None

# MQTT客户端初始化和连接
def init_mqtt_client():
    # MQTT配置
    MQTT_BROKER = get_param("MQTT_BROKER")
    MQTT_PORT = int(get_param("MQTT_PORT"))
    MQTT_USERNAME = get_param("MQTT_USERNAME")
    MQTT_PASSWORD = get_param("MQTT_PASSWORD")
    global client 
    client= mqtt.Client()
    client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
    
    def on_connect(client, userdata, flags, rc):
        if rc == 0:
            logger.info("MQTT客户端成功连接")
        else:
            logger.info(f"MQTT连接失败，错误码: {rc}")
    client.on_connect = on_connect
    try:
        client.connect(MQTT_BROKER, MQTT_PORT, 60)
        client.loop_start()
        return client
    except Exception as e:
        logger.info(f"MQTT连接异常: {str(e)}")
        return None


def get_mqtt_client():
    global client 
    if client is None:
        client= init_mqtt_client()
    return client    

def send_mqtt_request(payload: dict, timeout=5):
    """
    发送MQTT请求并等待响应
    """
    client = get_mqtt_client()
    if client is None:
        logger.error("MQTT客户端未初始化")
        return None
    
    # 生成唯一请求ID
    request_id = str(uuid.uuid4())
    payload["request_id"] = request_id
    
    # 创建响应存储对象
    response = {"status": "pending"}
    
    # 定义回调函数
    def on_message(client, userdata, msg):
        try:
            msg_data = json.loads(msg.payload.decode())
            if msg_data.get("request_id") == request_id:
                response["data"] = msg_data
                response["status"] = "completed"
        except Exception as e:
            logger.error(f"处理MQTT响应失败: {str(e)}")
    
    # 订阅响应主题
    client.on_message = on_message
    client.subscribe("/edge_app_controller_reply")
    
    # 发送请求
    client.publish("/edge_app_controller", json.dumps(payload))
    
    # 等待响应
    start_time = time.time()
    while time.time() - start_time < timeout:
        if response["status"] == "completed":
            return response["data"]
        time.sleep(0.1)
    
    logger.error(f"MQTT请求超时: {payload}")
    return None